wl_registry_bind(display_wayland->wl_registry, id, &wl_shell_interface, 1);
} else if (strcmp(interface, "wl_output") == 0) {
output =
- wl_registry_bind(display_wayland->wl_registry, id, &wl_output_interface, 1);
- _gdk_wayland_screen_add_output(display_wayland->screen, id, output);
+ wl_registry_bind(display_wayland->wl_registry, id, &wl_output_interface, 2);
+ _gdk_wayland_screen_add_output(display_wayland->screen, id, output, version);
/* We need another roundtrip to receive the modes and geometry
* events for the output, which gives us the physical properties
* and available modes on the output. */
void (* window_manager_changed) (GdkWaylandScreen *screen_wayland);
};
+#define OUTPUT_VERSION_WITH_DONE 2
+
struct _GdkWaylandMonitor
{
GdkWaylandScreen *screen;
guint32 id;
+ guint32 version;
struct wl_output *output;
GdkRectangle geometry;
int width_mm;
char * output_name;
char * manufacturer;
int refresh_rate;
+ gint scale;
};
G_DEFINE_TYPE (GdkWaylandScreen, _gdk_wayland_screen, GDK_TYPE_SCREEN)
*dest = monitor->geometry;
}
+static gint
+gdk_wayland_screen_get_monitor_scale_factor (GdkScreen *screen,
+ gint monitor_num)
+{
+ GdkWaylandScreen *screen_wayland = GDK_WAYLAND_SCREEN (screen);
+ GdkWaylandMonitor *monitor;
+
+ if (monitor_num >= screen_wayland->monitors->len)
+ return 1;
+
+ monitor = g_ptr_array_index(screen_wayland->monitors, monitor_num);
+
+ return monitor->scale;
+}
+
static GdkVisual *
gdk_wayland_screen_get_system_visual (GdkScreen * screen)
{
screen_class->get_monitor_plug_name = gdk_wayland_screen_get_monitor_plug_name;
screen_class->get_monitor_geometry = gdk_wayland_screen_get_monitor_geometry;
screen_class->get_monitor_workarea = gdk_wayland_screen_get_monitor_geometry;
+ screen_class->get_monitor_scale_factor = gdk_wayland_screen_get_monitor_scale_factor;
screen_class->get_system_visual = gdk_wayland_screen_get_system_visual;
screen_class->get_rgba_visual = gdk_wayland_screen_get_rgba_visual;
screen_class->is_composited = gdk_wayland_screen_is_composited;
monitor->manufacturer = g_strdup (make);
monitor->output_name = g_strdup (model);
- if (monitor->geometry.width != 0)
+ if (monitor->geometry.width != 0 && monitor->version < OUTPUT_VERSION_WITH_DONE)
{
g_signal_emit_by_name (monitor->screen, "monitors-changed");
update_screen_size (monitor->screen);
}
}
+static void
+output_handle_done(void *data,
+ struct wl_output *wl_output)
+{
+ GdkWaylandMonitor *monitor = (GdkWaylandMonitor *)data;
+
+ g_signal_emit_by_name (monitor->screen, "monitors-changed");
+ update_screen_size (monitor->screen);
+}
+
+static void
+output_handle_scale(void *data,
+ struct wl_output *wl_output,
+ uint32_t factor)
+{
+ GdkWaylandMonitor *monitor = (GdkWaylandMonitor *)data;
+
+ monitor->scale = factor;
+}
+
static void
output_handle_mode(void *data,
struct wl_output *wl_output,
monitor->geometry.height = height;
monitor->refresh_rate = refresh;
- g_signal_emit_by_name (monitor->screen, "monitors-changed");
- update_screen_size (monitor->screen);
+ if (monitor->geometry.width != 0 && monitor->version < OUTPUT_VERSION_WITH_DONE)
+ {
+ g_signal_emit_by_name (monitor->screen, "monitors-changed");
+ update_screen_size (monitor->screen);
+ }
}
static const struct wl_output_listener output_listener =
{
output_handle_geometry,
- output_handle_mode
+ output_handle_mode,
+ output_handle_done,
+ output_handle_scale,
};
void
_gdk_wayland_screen_add_output (GdkScreen *screen,
guint32 id,
- struct wl_output *output)
+ struct wl_output *output,
+ guint32 version)
{
GdkWaylandScreen *screen_wayland = GDK_WAYLAND_SCREEN (screen);
GdkWaylandMonitor *monitor = g_new0(GdkWaylandMonitor, 1);
monitor->id = id;
monitor->output = output;
+ monitor->version = version;
monitor->screen = screen_wayland;
+ monitor->scale = 1;
g_ptr_array_add(screen_wayland->monitors, monitor);
wl_output_add_listener(output, &output_listener, monitor);
return 0;
}
+
+guint32
+_gdk_wayland_screen_get_output_scale (GdkScreen *screen,
+ struct wl_output *output)
+{
+ GdkWaylandScreen *screen_wayland = GDK_WAYLAND_SCREEN (screen);
+ int i;
+
+ for (i = 0; i < screen_wayland->monitors->len; i++)
+ {
+ GdkWaylandMonitor *monitor = screen_wayland->monitors->pdata[i];
+
+ if (monitor->output == output)
+ return monitor->scale;
+ }
+
+ return 0;
+}